﻿<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" exclude-result-prefixes="xsl msxml dc slash wfw media evnet msxsl msc"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxml="urn:schemas-microsoft-com:xslt"
      xmlns:dc="http://purl.org/dc/elements/1.1/"
      xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
      xmlns:wfw="http://wellformedweb.org/CommentAPI/"
      xmlns:media="http://search.yahoo.com/mrss/"
      xmlns:evnet="http://www.mscommunities.com/rssmodule/"
      xmlns:msc="urn:msc-xslt"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
>

  <!-- Formats RSS format input into any intermediary format -->
  <xsl:output method="text" standalone="yes" indent="no" encoding="utf-8" omit-xml-declaration="yes" />
  <xsl:strip-space elements="*"/>
  <!-- These are the default values passed in by the XsltParsingProvider -->
  <xsl:param name="id" />
  <xsl:param name="title" />
  <xsl:param name="description" />
  <xsl:param name="feeduri" />
  <xsl:param name="updateinterval" />
  <xsl:param name="lastupdated" />
  <xsl:param name="parser" />
  <xsl:param name="maxitemcount" select="5"/>
  <xsl:param name="tagfilter" />  

  <msxsl:script language="CSharp" implements-prefix="msc">
    <![CDATA[
     public string replaceAll(string sSource, string sOld, string sNew){
       return sSource.Replace(sOld, sNew);
     }
     
     public string stripHtml(string sSource){
       return Regex.Replace(sSource, @"<(.|\n)*?>", string.Empty);     
     }
     
     public string RemoveReadMoreContent( string source )
     {
        return Regex.Replace( source, @"(\.{3}.*|\.{4}.*)", string.Empty );
     }
     
     /// <summary>
    ///     Truncate, and optionally cap the returned string
    /// </summary>
    /// <param name="s">The source string</param>
    /// <param name="length">The length at which to truncate</param>
    /// <param name="cap">Supplied optional cap such as '...'</param>
    /// <param name="ignoreMarkup">Ignore any embedded markup in the string so that it is counted in the length under consideration.</param>
    /// <returns>System.String</returns>
    public string Truncate( string source, int length, string cap, bool ignoreMarkup )
    {
        //-- Check if there are container HTML elements, if so, remove them as they effectively don't enter into the overall character count
        string tmpCheck = Regex.Replace( source, @"&lt;.*?&gt;|<.*?>", string.Empty, RegexOptions.IgnoreCase );
        char[] tmpChars = tmpCheck.ToCharArray();
        bool shouldCap = tmpChars.Length > length;

        //-- If we are capping, remove the cap length from the cutoff to ensure we get the right length of string back
        if( shouldCap )
        {
            char[] chars = source.ToCharArray();
            int cutoff = ( chars.Length > length ) ? length : chars.Length;
            int currCharIndex = 0;
            int charCount = 0;
            bool read = true;

            if( !string.IsNullOrEmpty( cap ) )
            {
                cutoff = cutoff - cap.Length;
            }

            StringBuilder charBuffer = new StringBuilder();

            while( read )
            {
                if( currCharIndex >= chars.Length )
                {                       
                    break;
                }

                while( currCharIndex < chars.Length )
                {
                    if( !ignoreMarkup )
                    {
                        if( chars[currCharIndex] == '<' )
                        {
                            for( int x = currCharIndex; x < chars.Length; x++ )
                            {
                                charBuffer.Append( chars[currCharIndex] );
                                currCharIndex++;
                                if( chars[x] == '>' )
                                {
                                    break;
                                }
                            }
                        }
                    }

                    if( charCount >= cutoff || currCharIndex >= chars.Length )
                    {
                        read = false;
                        break;
                    }
                    else
                    {
                        charBuffer.Append( chars[currCharIndex] );
                        currCharIndex++;
                        charCount++;
                    }
                }
            }

            if( !string.IsNullOrEmpty( cap ) )
            {
                return charBuffer.Append( cap ).ToString();
            }
            else
            {
                return charBuffer.ToString();
            }
        }
        return source;
    }
     
     //-- URGH!!!!!
     public string GetImageReference( string source )
     {
        source = source.ToLowerInvariant();
        if( source.IndexOf( "feeds.haacked.com" ) > 0 ) 
        {
          return "phil_haack.jpg";
        }
        else if( source.IndexOf( "misfitgeek.com" ) > 0 )
        {
          return "joe-stagner.jpg";
        } 
        else if( source.IndexOf( "blogs.msdn.com/brada" ) > 0 )
        {
          return "brad-abrams.jpg";
        }
        else if( source.IndexOf( "feeds.feedburner.com/StephenWalther" ) > 0 )
        {
          return "stephen-walther.png";
        } 
        else if( source.IndexOf( "stephenwalther" ) > 0 )
        {
          return "stephen-walther.png";
        }
        else if( source.IndexOf( "4guysfromrolla.com" ) > 0 )
        {
          return "4guysfromrolla.png";
        } 
        else if( source.IndexOf( "aspalliance.com" ) > 0 )
        {
          return "aspalliance.png";
        }
        else if( source.IndexOf( "aspsnippets.com" ) > 0 )
        {
          return "aspsnippets.png";
        } 
        else if( source.IndexOf( "damianedwards.wordpress.com" ) > 0 )
        {
          return "damienedwards.png";
        }
        else if( source.IndexOf( "blog.hmobius.com" ) > 0 )
        {
          return "danmaharry.png";          
        } 
        else if( source.IndexOf( "weblogs.asp.net/dwahlin" ) > 0 )
        {
          return "danwahlin.png";
        }
        else if( source.IndexOf( "blogs.ipona.com/davids" ) > 0 )
        {
          return "davesussman.png";
        } 
        else if( source.IndexOf( "weblogs.asp.net/fredriknormen" ) > 0 )
        {
          return "frederiknormen.png";
        }
        else if( source.IndexOf( "john.rummell.info" ) > 0 )
        {
          return "johnrummell.png";
        } 
        else if( source.IndexOf( "madskristensen.net" ) > 0 )
        {
          return "madskristensen.png";
        }
        else if( source.IndexOf( "www.west-wind.com/Weblog" ) > 0 )
        {
          return "rickstrahl.png";
        } 
        else if( source.IndexOf( "feedproxy.google.com/~r/ScottOnWriting" ) > 0 )
        {
          return "scottmitchell.png";
        }
        else if( source.IndexOf( "csharpbits.notaclue.net" ) > 0 )
        {
          return "stephennaughton.png";
        } 
        else if( source.IndexOf( "blog.tatham.oddie.com.au" ) > 0 )
        {
          return "tathamoddie.png";
        }
        else if( source.IndexOf( "blogs.msdn.com/Tess" ) > 0 )
        {
          return "tess-ferrandez.jpg";
        } 
        else if( source.IndexOf( "weblogs.asp.net/scottgu" ) > 0 )
        {
          return "scott-guthrie.jpg";
        }
        else if( source.IndexOf( "vishaljoshi.blogspot.com" ) > 0 )
        {
          return "vishal-joshi.jpg";
        } 
        else if( source.IndexOf( "weblogs.asp.net/bleroy" ) > 0 )
        {
          return "bertrand-le-roy.jpg";
        }
        else if( source.IndexOf( "www.jamessenior.com" ) > 0 )
        {
          return "JamesSenior.jpg";
        } 
        else if( source.IndexOf( "blogs.msdn.com/davidebb" ) > 0 )
        {
          return "david-ebbo.jpg";
        }
        else if( source.IndexOf( "weblogs.asp.net/davidfowler" ) > 0 )
        {
          return "david-fowler.jpg";
        }
        else if( source.IndexOf( "blogs.iis.net/bills" ) > 0 )
        {
          return "bill-staples.jpg";
        } 
        else if( source.IndexOf( "geekswithblogs.net/ranganh" ) > 0 )
        {
          return "harish-ranganathan.jpg";
        }
        else if( source.IndexOf( "www.hanselman.com" ) > 0 )
        {
          return "scott-hanselman.png";
        } 
        else if( source.IndexOf( "www.nikhilk.net" ) > 0 )
        {
          return "nikhil-kothari.jpg";
        }
        else if( source.IndexOf( "weblogs.asp.net/shankun" ) > 0 )
        {
          return "shanku-niyogi.jpg";
        } 
        else if( source.IndexOf( "blog.smarx.com" ) > 0 )
        {
          return "steve-marx.jpg"; 
        }
        else if( source.IndexOf( "blogs.msdn.com/petel" ) > 0 )
        {
          return "pete-lepage.jpg";
        } 
        else if( source.IndexOf( "blogs.msdn.com/bgold" ) > 0 )
        {
          return "brian-goldfarb.jpg";
        }
        else if( source.IndexOf( "blogs.msdn.com/sburk" ) > 0 )
        {
          return "shawn-burke.jpg";
        } 
        else if( source.IndexOf( "weblogs.asp.net/dannychen" ) > 0 )
        {
          return "danny-chen.jpg";
        }
        else if( source.IndexOf( "blogs.msdn.com/simonmu" ) > 0 )
        {
          return "simon-muzio.jpg";
        } 
        else if( source.IndexOf( "weblogs.asp.net/infinitiesloop" ) > 0 )
        {
          return "dave-reed.jpg";
        }
        else if( source.IndexOf( "blogs.msdn.com/eugeniop" ) > 0 )
        {
          return "eugenio-pace.jpg";
        } 
        else if( source.IndexOf( "blogs.msdn.com/mattgi" ) > 0 )
        {
          return "matt-gibbs.jpg";
        }
        else if( source.IndexOf( "blogs.iis.net/tomchris" ) > 0 )
        {
          return "tom-christian.jpg";
        } 
        else if( source.IndexOf( "blogs.msdn.com/mpuleio" ) > 0 )
        {
         return "michael-puleio.jpg"; 
        }
        else if( source.IndexOf( "blogs.msdn.com/scothu" ) > 0 )
        {
          return "scott-hunter.jpg";
        } 
        else if( source.IndexOf( "blogs.msdn.com/webdevelopertips" ) > 0 )
        {
          return "tipsandtricks.jpg";
        }
        else if( source.IndexOf( "blogs.msdn.com/webdevtools" ) > 0 )
        {
          return "tipsandtricks.jpg";
        }
        else
        {
          return "anonymous.jpg";
        }
     } 
     
     public string ParseDate( string date )
     {
      return DateTime.Parse( date ).ToString( "dddd, MMM dd" );
     }
          
    ]]>
  </msxsl:script>

  <xsl:template match="/">
    {
    "d":
    [
    <xsl:choose>
      <xsl:when test="$maxitemcount = -1">
        <xsl:choose>
          <xsl:when test="string-length($tagfilter) > 0">
            <xsl:variable name="tmpcount" select="count(rss/channel/item[category/text()=$tagfilter])" />
            <xsl:apply-templates select="rss/channel/item[category/text()=$tagfilter]">
              <xsl:with-param name="eof" select="$tmpcount" />
            </xsl:apply-templates>
          </xsl:when>
          <xsl:otherwise>
            <xsl:variable name="tmpcount" select="count(rss/channel/item)" />
            <xsl:apply-templates select="rss/channel/item">
              <xsl:with-param name="eof" select="$tmpcount" />
            </xsl:apply-templates>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="tmpcount" select="count(rss/channel/item)" />

        <xsl:variable name="trim">
          <xsl:choose>
            <xsl:when test="$tmpcount &gt; $maxitemcount">
              <xsl:value-of select="$maxitemcount"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$tmpcount"/>
            </xsl:otherwise>
          </xsl:choose>          
        </xsl:variable>
        
        <xsl:choose>
          <xsl:when test="string-length($tagfilter) > 0">
            <xsl:apply-templates select="rss/channel/item[position() &lt;= $trim][category/text()=$tagfilter]">
              <xsl:with-param name="eof" select="$trim" />
            </xsl:apply-templates>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="rss/channel/item[position() &lt;= $trim]">
              <xsl:with-param name="eof" select="$trim" />
            </xsl:apply-templates>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
    ]
    }
  </xsl:template>

  <xsl:template match="item">
    <xsl:param name="eof" />
    {
    "t": "<xsl:value-of select="msc:stripHtml(msc:replaceAll(msc:replaceAll(title/text(), '&quot;', '\&quot;'),'+','%2B'))" />",
    "l": "<xsl:value-of select="link/text()" />",
    "d": "<xsl:value-of select="msc:Truncate(msc:RemoveReadMoreContent(msc:stripHtml(msc:replaceAll(msc:replaceAll(msc:replaceAll(msc:replaceAll(description/text(), '&quot;', '\&quot;'), '&#x0d;', ''), '&#x0a;', ''), '&amp;#160;', ' '))),300,'...',false)" />",
    "p": "<xsl:value-of select="msc:ParseDate(pubDate/text())"/>",
    "i": "<xsl:choose><xsl:when test="string(enclosure/@url) != ''" ><xsl:value-of select="string(enclosure/@url)" /></xsl:when><xsl:otherwise>/asp.net/images/people/<xsl:value-of select="msc:GetImageReference(link/text())" /></xsl:otherwise></xsl:choose>",
    "a": "<xsl:call-template name="authorname">
      <xsl:with-param name="item" select="." />
    </xsl:call-template>"
    }
    <xsl:if test="$eof - position() > 0">
      <xsl:text>,</xsl:text>
    </xsl:if>
  </xsl:template>

  <xsl:template name="authorname">
    <xsl:param name="item" />

    <xsl:choose>
      <xsl:when test="string-length( $item/dc:creator ) > 0">
        <xsl:value-of select="msc:stripHtml(msc:replaceAll($item/dc:creator, '&quot;', '\&quot;' ))"/>
      </xsl:when>
      <xsl:when test="string-length( $item/author ) > 0">
        <xsl:value-of select="msc:stripHtml(msc:replaceAll($item/author, '&quot;', '\&quot;' ))"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>Unknown</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>